package com.stark.wechat.service.impl;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.stark.wechat.context.ApplicationContextUtil;
import com.stark.wechat.domain.Template;
import com.stark.wechat.form.Result;
import com.stark.wechat.message.template.TemplateMessage;
import com.stark.wechat.service.message.template.PushTemplateMessageService;
import com.stark.wechat.util.SysTools;
import com.stark.wechat.util.WechatUtil;

/**
 * 推送模板消息业务逻辑。
 * @author Ben
 * @since 1.0.0
 * @version 1.0.0, 2017/8/6
 */
@Service("pushTemplateMessageService")
public class PushTemplateMessageServiceImpl {
	Logger logger = LoggerFactory.getLogger(getClass());
	
	@Autowired
	private TemplateServiceImpl templateService;
	@Autowired
	private MessagePushServiceImpl messagePushService;
	
	/**
	 * 定时推送模板消息。
	 * @see #pushRegularly(TemplateMessage, Template)
	 */
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public void pushRegularly() {
		// 查询所有正在使用的模板
		List<Template> templateList = this.templateService.listEnable();
		// 遍历所有模板，调用相应 service ，通过其 generateTemplateMessages 方法获得所有待推送消息并推送
		String serviceName;
		PushTemplateMessageService pushService;
		List<TemplateMessage> msgList;
		for (Template template : templateList) {
			serviceName = template.getServiceName();
			try {
				pushService = (PushTemplateMessageService) ApplicationContextUtil.getBean(serviceName);
			} catch (Exception e) {
				logger.error("执行程序未定义：{}", serviceName, e);
				continue;
			}
			
			msgList = pushService.generateTemplateMessages();
			for (TemplateMessage msg : msgList) {
				try {
					this.pushRegularly(msg, template);
					
					System.out.println("推送模板消息成功："
							+ "templateName=" + msg.getTemplateName() + ","
							+ "openId=" + msg.getTouser());
				} catch (Exception e) {
					logger.error("推送消息失败：templateName={},openId={}",
							msg.getTemplateName(), msg.getTouser(), e);
				}
			}
		}
	}
	
	/**
	 * 推送单条模板消息。
	 * @param msg 模板消息对象。
	 * @param template 模板对象。
	 * @throws Exception 获取 access_token 时抛出异常。
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void pushRegularly(TemplateMessage msg, Template template) throws Exception {
		// 1、推送消息
		Result result = WechatUtil.pushTemplateMessage(SysTools.getAccessToken(), msg);
		if (!result.isSuccess()) {
			throw new RuntimeException(result.getErrmsg());
		}
		
		// 2、向 WECHAT_MESSAGE_PUSH 表中插入记录
		this.messagePushService.add(msg.getTouser(), template.getTemplateId(), SysTools.generateMessageContent(msg, template), msg.getEliminition());
	}
}
